package com.example.datasourcedemo.config;

import com.alibaba.fastjson.JSONObject;
import com.example.datasourcedemo.factory.DataSourceFactory;
import com.example.datasourcedemo.pojo.DataSourceRequest;
import com.zaxxer.hikari.HikariDataSource;
import io.micrometer.common.util.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import javax.sql.DataSource;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;

@Component
public class DataSourceManager {
    private final Map<String, DataSourceInfo> dataSourceMap = new ConcurrentHashMap<>();
    @Autowired
    private StringRedisTemplate redisTemplate;

    public String createDataSource(DataSourceRequest request) {
        String redisData = redisTemplate.opsForValue().get(request.getName());
        String token = UUID.randomUUID().toString();
        if (StringUtils.isEmpty(redisData)) {
            redisTemplate.opsForValue().set(request.getName(), token);
            DataSource dataSource = DataSourceFactory.createDataSource(request.getIp(), request.getPort(), request.getUsername(), request.getPassword(), request.getType());
            dataSourceMap.put(token, new DataSourceInfo(dataSource, request.getType()));
            return token;
        } else {
            return redisData;
        }
        // String token = UUID.randomUUID().toString();
        // DataSource dataSource = DataSourceFactory.createDataSource(ip, port, username, password, type);
        // dataSourceMap.put(token, new DataSourceInfo(dataSource, type));
        // return token;
    }

    public DataSourceInfo getDataSourceInfo(String token) {
        return dataSourceMap.get(token);
    }

    public void removeDataSource(String token) {
        DataSourceInfo info = dataSourceMap.remove(token);
        if (info != null && info.getDataSource() instanceof HikariDataSource) {
            ((HikariDataSource) info.getDataSource()).close();
        }
    }

    public static class DataSourceInfo {
        private DataSource dataSource;
        private String type;

        public DataSourceInfo(DataSource dataSource, String type) {
            this.dataSource = dataSource;
            this.type = type;
        }

        // Getters
        public DataSource getDataSource() {
            return dataSource;
        }

        public String getType() {
            return type;
        }
    }
}
